package com.waya.web.browser.manager;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.support.annotation.Nullable;
import android.view.KeyEvent;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.waya.web.browser.event.EventHandlerImp;
import com.waya.web.browser.player.view.MediaPlayerLayout;
import com.waya.web.browser.util.CallJsUtil;
import com.waya.web.browser.util.WebCookieUtil;
import com.waya.web.browser.webview.WanbaEpgInterface;
import com.waya.web.browser.webview.WebBuilder;
import com.waya.web.browser.webview.WebDefaultSetting;
import com.waya.web.browser.webview.WebDefaultViewClient;

import java.lang.ref.WeakReference;
import java.util.List;

import org.jetbrains.annotations.NotNull;

/**
 * Created by JesseHev on 2017/12/4.
 * describe: webview 管理类
 */

public class WbWebManager {

    private static volatile WbWebManager INSTANCE = null;

    private WebCookieUtil mCookieUtil;

    private WebBuilder mWebBuilder;

    private EventHandlerImp mHandlerImp;

    private CallJsUtil mCallJsUtil;

    private Context mContext;

    private WeakReference mReferenceContext;

    public WbWebManager(Context context) {
        mReferenceContext = new WeakReference(context);
        mContext = (Context) mReferenceContext.get();
        if (mContext == null) {
            throw new IllegalArgumentException("context must not be null...");
        }
        mCookieUtil = new WebCookieUtil(mContext);
        mWebBuilder = new WebBuilder(mContext);
        mCallJsUtil = new CallJsUtil();
    }


    public static WbWebManager getInstance(Context context) {

        if (INSTANCE == null) {
            synchronized (WbWebManager.class) {
                INSTANCE = new WbWebManager(context);
            }
        }
        return INSTANCE;
    }

    /**
     * 获取cookie
     */
    public String getCookieByUrl(String url) {
        return mCookieUtil.getCookie(url);
    }

    /**
     * 同步cookie
     *
     * @param url    请求地址
     * @param cookie 需要同步的cookie
     */
    public WbWebManager setCookie(String url, String cookie) {
        //removeExpiedCookie();
        mCookieUtil.syncCookie(url, cookie);
        return this;
    }

    /**
     * 同步多条cookie
     *
     * @param url     请求地址
     * @param cookies cookies集
     */
    public WbWebManager setCookies(String url, List<String> cookies) {
        mCookieUtil.syncCookies(url, cookies);
        return this;
    }

    /**
     * 清除cookie
     */
    public void removeAllCookies() {
        removeAllCookies(null);
    }

    /**
     * 清除cookie
     */
    public void removeAllCookies(@Nullable ValueCallback<Boolean> callback) {
        mCookieUtil.removeAllCookies(callback);
    }

    /**
     * 清除过期的cookie
     */
    public void removeExpiedCookie() {
        mCookieUtil.removeExpirdCookie();
    }

    /**
     * 设置webview默认属性
     */
    public WbWebManager setSetting() {
        return setSetting(null);
    }

    /**
     * 设置webview自定义属性
     */
    public WbWebManager setSetting(WebSettings setting) {
        if (setting == null) {
            mWebBuilder.setting(WebDefaultSetting.getInstance().toSetting(getTarget()).getWebSettings());
            return this;
        }
        mWebBuilder.setting(setting);
        return this;
    }

    /**
     * 如果当前是dialog形式显示webview 需要调用该方法
     *
     * @param dialog
     */
    public WbWebManager dialog(Dialog dialog) {
        mWebBuilder.dialog(dialog);
        return this;
    }


    public WebSettings getSetting() {
        return mWebBuilder.getSetting();
    }


    public WbWebManager setTarget(@NotNull WebView webView) {
        mWebBuilder.target(webView);
        return this;
    }

    public WebView getTarget() {
        return mWebBuilder.getWebView();
    }


    public WbWebManager setCallback(@NotNull WanbaEpgInterface.Callback callback) {
        if (callback == null) {
            throw new NullPointerException("callback not be set null...");
        }
        mWebBuilder.setCallback(callback);
        return this;
    }

    public WbWebManager setWebClient(WebViewClient clien) {
        mWebBuilder.client(clien);
        return this;
    }

    public WbWebManager setChromClient(WebChromeClient chromeClicent) {
        mWebBuilder.chromeClicent(chromeClicent);
        return this;
    }

    public WbWebManager palyerLayout(MediaPlayerLayout layout) {
        mWebBuilder.playerLayout(layout);
        return this;
    }

    public WbWebManager registerJsObj() {
        mWebBuilder.registerJsObj();
        return this;
    }


    public void load(String url) {
        mWebBuilder.load(url).build();
    }


    public boolean back() {
        if (mHandlerImp == null) {
            mHandlerImp = EventHandlerImp.getInstance(getTarget(), mWebBuilder.getUrl());
        }
        return mHandlerImp.back();
    }

    /**
     * 发送apk安装的通知
     *
     * @param activity activity对象
     * @param funcName js方法名字（和js一致）
     * @param result   通知结果 （json格式）
     */
    private void sendInstallResult(Activity activity, String funcName, String result) {
        callJs(activity, funcName, result, CallJsUtil.ACTION_INSTALL_APK);
    }

    /**
     * 发送apk卸载的通知
     *
     * @param activity activity对象
     * @param funcName js方法名字（和js一致）
     * @param result   通知结果 （json格式）
     */
    private void sendUnInstallResult(Activity activity, String funcName, String result) {
        callJs(activity, funcName, result, CallJsUtil.ACTION_UNINSTALL_APK);
    }

    private void callJs(Activity activity, String funcName, String result, String action) {
        mCallJsUtil.setWebView(getTarget()).callJs(funcName, result);
    }

    public void callJs(String funcName, String result) {
        mCallJsUtil.setWebView(getTarget()).callJs(funcName, result);
    }

    public WbWebManager setErrorPage(String url) {
        WebViewClient viewClient = mWebBuilder.getClient();
        if (viewClient == null || !(viewClient instanceof WebDefaultViewClient)) {
            throw new ClassFormatError(
                    "set self error page, webViewClient instanceof WebDefaultViewClient");
        }
        ((WebDefaultViewClient) viewClient).setLoadErrorUrl(url);
        return this;
    }

    public void destroy() {
        mWebBuilder.destroy();
    }
}
